package mirrormonkey.util.annotations.parsing;

import junit.framework.Assert;
import mirrormonkey.util.annotations.control.IRClass;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.DeclareInvalidNormalOverride;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.ExtendingClassIR;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.InvalidFirstExtendingIR;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.InvalidSecondExtendingIR;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.TestContainer.DeclareExtendingIR;
import mirrormonkey.util.annotations.parsing.classlevel.FlatMemberlessClassIRManagementTest.TestContainer.DeclareNoIR;

import org.junit.Test;

/**
 * Contains test cases concerning compatibility for possible exchanges of
 * <tt>AnnotationParser</tt> for an extending class.
 * 
 * @author Philipp Christian Loewner
 * 
 */
public class AnnotationParserExtendTest {

	/**
	 * Tests if it is possible to extend <tt>AnnotationParser</tt> to define an
	 * own parsing control flow
	 */
	@Test
	public void testExtendParser() {
		AnnotationParser parser = new AnnotationParser() {
		};
		ClassIR cir = parser.parseClass(DeclareExtendingIR.class, null);
		Assert.assertNotNull(cir);
		Assert.assertEquals(ExtendingClassIR.class, cir.getClass());
	}

	@IRClass(ExtendingClassIR.class)
	public static class ExtendingParser extends AnnotationParser {
	}

	/**
	 * Tests if it is possible to override the default class IR when extending
	 * <tt>AnnotationParser</tt>.
	 */
	@Test
	public void testOverrideParserDefault() {
		AnnotationParser parser = new ExtendingParser();
		ClassIR cir = parser.parseClass(DeclareNoIR.class, null);
		Assert.assertNotNull(cir);
		Assert.assertEquals(ExtendingClassIR.class, cir.getClass());
	}

	@IRClass(InvalidFirstExtendingIR.class)
	public static class ExtendingParserInvalidDefaultIR extends
			AnnotationParser {
	}

	/**
	 * Tests if using an IR class that does not support being the first IR
	 * instantiated for a parsed class as default IR provokes an exception.
	 */
	@Test(expected = RuntimeException.class)
	public void testInvalidOverrideParserDefault() {
		AnnotationParser parser = new ExtendingParserInvalidDefaultIR();
		parser.parseClass(DeclareNoIR.class, null);
	}

	@IRClass(InvalidSecondExtendingIR.class)
	public static class ExtendingParserInvalidSecondIR extends AnnotationParser {
	}

	/**
	 * Tests if using an IR class that does only support being used as default
	 * as default does not provoke an exception.
	 */
	@Test
	public void testInvalidNormalOverrideDefault() {
		AnnotationParser parser = new ExtendingParserInvalidSecondIR();
		parser.parseClass(DeclareInvalidNormalOverride.class, null);
	}

}
